package game;

import game.gfx.Screen;
import game.gfx.SpriteSheet;
import game.level.Level;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

public class Game extends Canvas implements Runnable
{
	private static final int WIDTH = 30*8;
	private static final int HEIGHT = 30*8;
	private static final int SCALE = 4;
		
	public boolean running = false;
	private int maxFPS = 60;
		
	SpriteSheet sheet;
	Level level;	
	Screen screen;

	private static BufferedImage levelI = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
	public static int[] pixels = ((DataBufferInt) levelI.getRaster().getDataBuffer()).getData();	
	
	public Game()
	{
		this.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		this.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		this.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
	}
	
	public void init()
	{
		sheet = new SpriteSheet("/res/sprite_sheet.png");
		level = new Level("/res/levels/large_test_level_2.png", sheet);

		screen = new Screen(level, WIDTH, HEIGHT);
	}
	
	public synchronized void start()
	{
		running = true;
		new Thread(this).start();
	}
	
	public synchronized void stop()
	{
		running = false;
	}
	
	public void run()
	{
		long lastTime = System.nanoTime();
		double nsPerTick = 1000000000D / 60D;
		
		int ticks = 0;
		int frames = 0;
		
		long lastTimer = System.currentTimeMillis();
		double delta = 0;
		
		init();
		
		while(running)
		{
			long now = System.nanoTime();
			delta += (now - lastTime) / nsPerTick;
			lastTime = now;
			
			boolean shouldRender = true;
			
			while(delta >= 1)
			{
				ticks++;
				tick();
				delta -= 1;		
				shouldRender = true;
			}
			
			try { Thread.sleep(1000 / maxFPS); }
			catch (InterruptedException e) { e.printStackTrace(); }
			
			if (shouldRender)
			{
				frames++;
				render();
			}
			
			if (System.currentTimeMillis() - lastTimer >= 1000)
			{
				lastTimer += 1000;
				Main.frame.setTitle(ticks + " ticks, " + frames + " frames.");
				frames = 0;
				ticks = 0;
			}
		}
	}
	
	public void tick()
	{
		level.tick();
	}
	
	public void render()
	{
		BufferStrategy bs = getBufferStrategy();
		if (bs == null)
		{
			createBufferStrategy(3);
			return;
		}
		
		screen.renderLevel();
		
		Graphics levelG = bs.getDrawGraphics();
		
		levelG.setColor(Color.BLACK);
		levelG.fillRect(0, 0, getWidth(), getHeight());
		
		levelG.drawImage(levelI, 0, 0, getWidth(), getHeight(), null);
				
		levelG.dispose();
		bs.show();
	}

}
